<?php
/////////////////////////////////////////////////////////////////////////////
// 
//
// workflow_system
//
// workflow_copyright
// 
/////////////////////////////////////////////////////////////////////////////

/**
 * FILE_NAME : mysqli.core.php   FILE_PATH : D:\webroot\_own\classes\core\mysqli.core.php
 * ....mysqli操作类
 *
 * @copyright workflow_system 
 * @author workflow Develop Team 
 * @package 
 * @subpackage 
 * @version Wed Feb 20 15:20:31 CST 2008
 */

class DBEngine {
	/**
	 * 负责读数据库的数据库连接对象
	 *
	 * @var object
	 */
	var $_conn;
	/**
	 * 负责写数据库的数据库连接对象
	 *
	 * @var object
	 */
	var $_conn_write;
	/**
	 * 数据库表前缀
	 *
	 * @var string
	 */
	var $_dbprefix;

	/**
	 * 是否调试信息
	 *
	 * @var boolen
	 */
	var $ifdebug = false;

	/**
	 * 当前的数据库连接
	 *
	 * @var int
	 */
	var $conn;
	/**
	 * 其他数据库连接
	 *
	 * @var string
	 */
	var $_sys_conn_conn;
	var $_sys_conn_write;

	/**
	 * 使用UTF-8编码存取数据
	 *
	 * @var string
	 */
	var $utf_String = "
                 SET CHARACTER_SET_CLIENT = utf8,
                 CHARACTER_SET_CONNECTION = utf8,
                 CHARACTER_SET_DATABASE = utf8,
                 CHARACTER_SET_RESULTS = utf8,
                 CHARACTER_SET_SERVER = utf8,
                 COLLATION_CONNECTION = utf8_general_ci,
                 COLLATION_DATABASE = utf8_general_ci,
                 COLLATION_SERVER = utf8_general_ci,
                 AUTOCOMMIT=1
	       ";

	/**
	 * 连接数据库
	 *
	 */
	function _dbinitialize(){
		
		if (!function_exists( 'mysql_connect' )) {
			$this->halt("请检查是否安装mysql数据库或php是否加载mysql功能模块");
		}
		/**
		 * 读数据库连接
		 */
		if (!($conn = mysqli_connect( $GLOBALS['dbconfig']['servername_read'], $GLOBALS['dbconfig']['username_read'], $GLOBALS['dbconfig']['password_read'],$GLOBALS['dbconfig']['databasename_read'] ))) {
			$this->halt("mysql数据库连接失败，请检查相关配置文件");
		}

		/**
		 * 如果是读写分开的，写数据库连接
		 */
		if ($GLOBALS['dbconfig']['database_read_write'] == 1){
			if (!($conn_write = @mysqli_connect( $GLOBALS['dbconfig']['servername_write'], $GLOBALS['dbconfig']['username_write'], $GLOBALS['dbconfig']['password_write'],$GLOBALS['dbconfig']['databasename_write'] ))) {
				$this->halt("mysql数据库连接失败，请检查相关配置文件");
			}
		}else{
			$conn_write = $conn;
		}

		/**
		 * 设置表前缀
		 */
		$this->_dbprefix = $GLOBALS['dbconfig']['dbprefix'];
		$this->_conn = $conn;
		$this->_conn_write = $conn_write;
		if ($GLOBALS['dbconfig']['ifdebug'] == "true"){
			$this->ifdebug = true;
		}
		else{
			$this->ifdebug = false;
		}
	}

	/**
	 * 执行SQL语句
	 *
	 * @param string $sql
	 * @param string $link
	 * @return var
	 */
	function query($sql,$link){
		if ($link){
			$this->conn = $link;
			mysqli_query($link,$this->utf_String);
			$this->halt("(mysql 语句):".$sql , "1");	
			$result = mysqli_query($link,$sql);

			if (!$result) {
				$this->halt("SQL 無效: ".$sql);
			}
		}
		return $result;
	}

	/**
	 * 将SQL语句里的表名称加上配置文件里的前缀
	 * 表名称必须用``括起来
	 * 返回值为加上了表前缀的SQL语句
	 * 例如，_settablename("select * from `member`")
	 * 得到的结果为，select * from `shopnc_member`
	 *
	 * @param string $strsql  SQL语句
	 * @return string
	 */
	function _settablename($strsql){
		if ($this->_dbprefix == ''){
			return $strsql;
		}
		$sqlarray = explode("`",$strsql);
		if (!is_array($sqlarray)){
			return $strsql;
		}else{
			for ($i=0;$i<count($sqlarray);$i++){
				if (($i+1)%2 == 0){
					if ($sqlarray[$i] == "")
					echo $strsql;
					if (!strstr($sqlarray[$i],$this->_dbprefix))
					$sqlarray[$i] = $this->_dbprefix . $sqlarray[$i];
				}
			}
			return implode("`",$sqlarray);
		}
	}


	/**
	 * 根据SQL查询语句，得到一定范围内的记录数组
	 * 例如，得到前10条记录：SelectLimit("select * from `member` ",10,0)
	 * 得到的结果形式如$rs[行号][列名]
	 * 
	 * @param string $strsql  sql查询语句
	 * @param int $count  需要的记录数
	 * @param int $offset  从第几条开始
	 * @return var[] 二维数组
	 */
	function SelectLimit($strsql,$count,$offset){
		$strsql = $this->_settablename($strsql);
		$exe_sql = $strsql . " limit $offset,$count";
		return $this->GetArray($exe_sql);
	}

	/**
	 * 根据参数产生SQL插入语句
	 *
	 * @param object $tablename 要插入的表名称
	 * @param var[] $array 要插入的字段值，一维数组格式，$arr[列名] = 值
	 * @return string 返回的SQL语句
	 */
	function GetInsertSQL($tablename,$array){
		$sql = $this->_settablename("insert into `$tablename` ");
		foreach ($array as $k=>$v){
			$sub_sql .= "" . $k . ",";
		}

		if (substr($sub_sql,strlen($sub_sql)-1,1) == ","){
			$sub_sql = substr($sub_sql,0,strlen($sub_sql)-1);
		}
		$sub_sql = "(" . $sub_sql . ") values (";
		foreach ($array as $k=>$v){
			$sub_sql .= "'" . $v . "',";
		}
		if (substr($sub_sql,strlen($sub_sql)-1,1) == ","){
			$sub_sql = substr($sub_sql,0,strlen($sub_sql)-1);
		}
		$sub_sql = $sub_sql . ")";
		return $sql . $sub_sql;
	}

	/**
	 * 根据参数产生SQL更新语句
	 *
	 * @param object $tablename 要插入的表名称
	 * @param var[] $array 要更新的字段值，一维数组格式，$arr[列名] = 值
	 * @param object $wheresql 更新条件
	 * @return string 返回的SQL语句
	 */
	function GetUpdateSQL($tablename,$array,$wheresql="",$intfield=false){
		$sql = $this->_settablename("update `$tablename` set ");
		foreach ($array as $k=>$v){
			if($intfield === false){
				$sub_sql .= "$k='" . $v . "',";
			}else{
				$sub_sql .= "$k=" . $v . ",";
			}
		}
		if (substr($sub_sql,strlen($sub_sql)-1,1) == ","){
			$sub_sql = substr($sub_sql,0,strlen($sub_sql)-1);
		}
		return $sql . $sub_sql . " " . $wheresql;
	}

	/**
	 * 执行SQL语句
	 *
	 * @param string $strsql sql语句
	 * @return var
	 */
	function Execute($strsql){
		$strsql = $this->_settablename($strsql);
		if (strtolower(substr($strsql,0,6)) == "select"){
			//如果是查询那么用读数据库连接对象执行
			return $this->query($strsql,$this->_conn);
		}else{
			//如果是需要对数据库进行更改的操作那么用写数据库连接对象执行
			return $this->query($strsql,$this->_conn_write);
		}
	}

	/**
	 * 得到一行信息放到数组中
	 *
	 * @param string $strsql SQL查询语句
	 * @return var[] 一维数组，形式如，$arr[列名]
	 */
	function GetRow($strsql){
		$strsql = $this->_settablename($strsql);
		$result = $this->query($strsql,$this->_conn);
		$row = $this->fetch_array($result);
		if ($record){
			return $record;
		}else{
			return array();
		}
	}

	/**
	 * 查询SQL语句，结果生成一个二维数组
	 * 形式如，$arr[行号][列名]
	 *
	 * @param string $strsql
	 * @return var[]
	 */
	function GetArray($strsql){
		$strsql = $this->_settablename($strsql);
		$result = $this->query($strsql,$this->_conn);
		$array = array();
		while($row = $this->fetch_array($result)){
			$array[] = $row;
		}

		return (array)$array;
	}

	/**
	 * 执行SQL指令，并且以阵列的方式回传第一笔记录的第一个栏位。资料集及其馀的记录将会被自动清除，如果发生错误，就回传 false 值。
	 *
	 * @param string $strsql
	 * @return var
	 */
	function GetOne($strsql){
		$strsql = $this->_settablename($strsql);
		$array = $this->SelectLimit($strsql,1,0);
		return $array[0][0];
	}


	function geterrdesc() {
		$this->error = @mysqli_error($this->conn);
		return $this->error;
	}

	function geterrno() {
		$this->errno = @mysqli_errno($this->conn);
		return $this->errno;
	}


	/**
	 * 得到记录集中某行信息
	 *
	 * @param int $queryid
	 * @return var[]
	 */
	function fetch_array($queryid) {
		if (empty($queryid)){
			$this->halt("Query id 无效:".$queryid , "1");
		}else{
			$record = mysqli_fetch_array($queryid);}
			return $record;
	}

	function halt($msg,$type="0"){
		if ($this->ifdebug == true){
			echo "<hr NOSHADE SIZE=1><br>";

			if ($type == "0"){
				echo "<b>" . $this->geterrno() . " : " . $this->geterrdesc() . "</b><br>";
			}


			echo $msg . "<br>";
		}
		echo "<br />Database Error #1001!";exit;
	}
	
	/**
	 * 得到字段名称
	 *
	 * @param int $result
	 * @param int $f_index
	 * @return string
	 */
	function FetchField($result,$f_index){
		return mysqli_field_name($result,$f_index);
	}

	/**
	 * 得到结果集的字段数量
	 *
	 * @param int $result
	 * @return string[]
	 */
	function FieldCount($result){
		return mysqli_num_fields($result);
	}
	
	/**
	 * 连接到其他数据库，其他数据库没有读写分离，在使用后需要执行clearconnect。未clearconnect前执行的操作都是针对这个数据库的。
	 *
	 * @param string $databasename
	 */
	function connect($databasename){
		/**
		 * 读数据库连接
		 */
		if (!($connother = mysqli_connect( $GLOBALS['dbconfig']['servername_read'], $GLOBALS['dbconfig']['username_read'], $GLOBALS['dbconfig']['password_read'],$databasename ))) {
			$this->halt("mysql数据库连接失败，请检查相关配置文件");
			return false;
		}else{
			if (!mysql_select_db($databasename,$connother)) {
				$this->halt("连接到数据库失败，请检查相关配置文件");
				return false;
			}
		}
		$this->_sys_conn_conn = $this->_conn;
		$this->_sys_conn_conn_write = $this->_conn_write;
		$this->_conn = $connother;
		$this->_conn_write = $connother;
		return true;
	}
	
	/**
	 * 恢复数据库的连接
	 *
	 */
	function clearconnect(){
		$this->_conn = $this->_sys_conn_conn;
		$this->_conn_write = $this->_sys_conn_conn_write;
	}


}
?>